<html>
    <head>
        <title>对象扩展管理器</title>
    </head>
    <body>
        <script>
            /*
                        二、对象扩展管理器

                                 虽然你可以为可扩展对象(实现IHasExtraProperties接口的)设置任意属性，但 ObjectExtensionManager用于显式定义可扩展类的额外属性。

                                 显式定义额外属性有一些用例：

                                    1、 允许控制如何在对象到对象映射上处理额外的属性。

                                    2、 允许为属性定义元数据。 例如，你可以在使用EF Core 时将额外的属性映射到数据库中的表字段。

                                ObjectExtensionManager 实现单例模式(ObjectExtensionManager.Instance),你应该在应用程序启动前定义对象扩展。

                                应用程序启动模板有一些预定义的静态类来安全地定义内部的对象扩展。


                                1、AddOrUpdate() 方法 （添加或更新对象）
                                        AddOrUpdate是为对象定义额外属性或更新额外属性的主要方法。

                                        eg:  为 IdentityUser 实体定义额外属性：、

                                            ObjectExtensionManager.Instance.AddOrUpdate<IdentityUser>(options=>{
                                                
                                                options.AddOrUpdateProperty<string>("SocialSecurityNumber");

                                                options.AddOrUpdateProperty<bool>("IsSuperUser");
                                            });

                                2、AddOrUpdateProperty() 方法，(添加或更新属性)

                                            虽然AddOrUpdateProperty可以在options上使用，如前所示，但如果要定义一个额外的属性，也可以使用快捷方式扩展方法：
                                                        
                                                    ObjectExtensionManager.Instance
                                                                    .AddOrUpdateProperty<IdentityUser, string>("SocialSecurityNumber");

                                            有时为多个类型定义一个额外的属性会很实用。你可以使用以下代码，而不是一个接一个地定义：

                                                      ObjectExtensionManager.Instance
                                                                            .AddOrUpdateProperty<string>(
                                                                                new[]
                                                                                {
                                                                                    typeof(IdentityUserDto),
                                                                                    typeof(IdentityUserCreateDto),
                                                                                    typeof(IdentityUserUpdateDto)
                                                                                },
                                                                                "SocialSecurityNumber"
                                                                            );

                                3、属性配置
                                            AddOrUpdateProperty还可以获取一个可以对属性定义执行附加配置的操作：

                                                    ObjectExtensionManager.Instance
                                                                          .AddOrUpdateProperty<IdentityUser, string>(
                                                                                "SocialSecurityNumber",
                                                                                options =>
                                                                                {
                                                                                    //Configure options...
                                                                                });

                                            options有一个名为Configuration的字典，它使对象扩展定义甚至可以扩展EF Core使用它将额外的属性映射到数据库中的表字段。请参阅扩展实体文档。

                                            以下部分解释了基本的属性配置选项：

                                                    ①、默认值： 
                                                            自动为新属性设置默认值，这是属性类型的自然默认值，例如string的null，false或int的0。

                                                            有两种方法可以设置默认值：
                                                                1、 DefaultValue选项属性：
                                                                             DefaultValue选项可以设置为任何值：   
                                                                                    ObjectExtensionManager.Instance
                                                                                                        .AddOrUpdateProperty<IdentityUser, int>(
                                                                                                            "MyIntProperty",
                                                                                                            options =>
                                                                                                            {
                                                                                                                options.DefaultValue = 42;
                                                                                                            });
                                                                                                                  
                                                                2、DefaultValueFactory选项：

                                                                             DefaultValueFactory可以设置为返回默认值的函数：
                                                                                    ObjectExtensionManager.Instance
                                                                                                        .AddOrUpdateProperty<IdentityUser, DateTime>(
                                                                                                            "MyDateTimeProperty",
                                                                                                            options =>
                                                                                                            {
                                                                                                                options.DefaultValueFactory = () => DateTime.Now;
                                                                                                            });
                                                            options.DefaultValueFactory的优先级高于options.DefaultValue。

                                                            提示：仅当默认值可能随时间变化时才使用DefaultValueFactory选项（如本例中的DateTime.Now）。如果它是一个常量值，则使用DefaultValue选项。
                    */
        </script>
    </body>
</html>